name: bun-linux

concurrency:
  group: bun-linux-build-${{ github.ref }}
  cancel-in-progress: true

on:
  push:
    branches:
      - main
    paths:
      - ".github/workflows/bun-linux-build.yml"
      - "src/**/*"
      - "test/**/*"
      - "packages/bun-usockets/src/**/*"
      - "packages/bun-uws/src/**/*"
      - "CMakeLists.txt"
      - "build.zig"
      - "Makefile"
      - "Dockerfile"
  pull_request:
    branches:
      - main
    paths:
      - ".github/workflows/bun-linux-build.yml"
      - "src/**/*"
      - "test/**/*"
      - "packages/bun-usockets/src/**/*"
      - "packages/bun-uws/src/**/*"
      - "CMakeLists.txt"
      - "build.zig"
      - "Makefile"
      - "Dockerfile"
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  linux:
    name: ${{matrix.tag}}
    runs-on: ${{matrix.runner}}
    if: github.repository_owner == 'oven-sh'
    timeout-minutes: 90
    permissions: write-all
    strategy:
      fail-fast: false
      matrix:
        include:
          - cpu: haswell
            tag: linux-x64
            arch: x86_64
            build_arch: amd64
            runner: namespace-profile-bun-linux-x64
            build_machine_arch: x86_64
            assertions: "OFF"
            zig_optimize: "ReleaseFast"
            target: "artifact"
          - cpu: nehalem
            tag: linux-x64-baseline
            arch: x86_64
            build_arch: amd64
            runner: namespace-profile-bun-linux-x64
            build_machine_arch: x86_64
            assertions: "OFF"
            zig_optimize: "ReleaseFast"
            target: "artifact"
          # - cpu: haswell
          #   tag: linux-x64-assertions
          #   arch: x86_64
          #   build_arch: amd64
          #   runner: big-ubuntu
          #   build_machine_arch: x86_64
          #   assertions: "ON"
          #   zig_optimize: "ReleaseSafe"
          #   target: "artifact-assertions"
          # - cpu: nehalem
          #   tag: linux-x64-baseline-assertions
          #   arch: x86_64
          #   build_arch: amd64
          #   runner: big-ubuntu
          #   build_machine_arch: x86_64
          #   assertions: "ON"
          #   zig_optimize: "ReleaseSafe"
          #   target: "artifact-assertions"

    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
          ref: ${{github.sha}}
          clean: true
      - name: Run
        run: |
          rm -rf ${{runner.temp}}/release
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: false
          build-args: |
            ARCH=${{matrix.arch}}
            BUILDARCH=${{matrix.build_arch}}
            BUILD_MACHINE_ARCH=${{matrix.build_machine_arch}}
            CPU_TARGET=${{matrix.cpu}}
            GIT_SHA=${{github.sha}}
            ASSERTIONS=${{matrix.assertions}}
            ZIG_OPTIMIZE=${{matrix.zig_optimize}}
          platforms: linux/${{matrix.build_arch}}
          target: ${{matrix.target}}
          outputs: type=local,dest=${{runner.temp}}/release
      - id: bun-version-check
        name: Bun version check
        run: |
          # If this hangs, it means something is seriously wrong with the build
          ${{runner.temp}}/release/bun-profile --version
      - name: Zip
        run: |
          # if zip is not found
          if [ ! -x "$(command -v zip)" ]; then
            sudo apt-get update && sudo apt-get install -y zip --no-install-recommends
          fi

          if [ ! -x "$(command -v strip)" ]; then
            sudo apt-get update && sudo apt-get install -y binutils --no-install-recommends
          fi

          cd ${{runner.temp}}/release
          chmod +x bun-profile bun

          mkdir bun-${{matrix.tag}}-profile
          mkdir bun-${{matrix.tag}}

          strip bun

          mv bun-profile bun-${{matrix.tag}}-profile/bun-profile
          mv bun bun-${{matrix.tag}}/bun

          zip -r bun-${{matrix.tag}}-profile.zip bun-${{matrix.tag}}-profile
          zip -r bun-${{matrix.tag}}.zip bun-${{matrix.tag}}
      - uses: actions/upload-artifact@v4
        with:
          name: bun-${{matrix.tag}}-profile
          path: ${{runner.temp}}/release/bun-${{matrix.tag}}-profile.zip
      - uses: actions/upload-artifact@v4
        with:
          name: bun-${{matrix.tag}}
          path: ${{runner.temp}}/release/bun-${{matrix.tag}}.zip
      - uses: actions/upload-artifact@v4
        with:
          name: bun-obj-${{matrix.tag}}
          path: ${{runner.temp}}/release/bun-obj
      - uses: actions/upload-artifact@v4
        with:
          name: ${{matrix.tag}}-dependencies
          path: ${{runner.temp}}/release/bun-dependencies
      - name: Release
        id: release
        uses: ncipollo/release-action@v1
        if: |
          github.repository_owner == 'oven-sh'
          && github.ref == 'refs/heads/main'
        with:
          prerelease: true
          body: "This canary release of Bun corresponds to the commit [${{ github.sha }}]"
          allowUpdates: true
          replacesArtifacts: true
          generateReleaseNotes: true
          artifactErrorsFailBuild: true
          token: ${{ secrets.GITHUB_TOKEN }}
          name: "Canary (${{github.sha}})"
          tag: "canary"
          artifacts: "${{runner.temp}}/release/bun-${{matrix.tag}}.zip,${{runner.temp}}/release/bun-${{matrix.tag}}-profile.zip"
      - uses: sarisia/actions-status-discord@v1
        if: failure() && github.repository_owner == 'oven-sh' && github.event_name == 'pull_request'
        with:
          title: ""
          webhook: ${{ secrets.DISCORD_WEBHOOK }}
          status: ${{ job.status }}
          noprefix: true
          nocontext: true
          description: |
            Pull Request
            ### [${{github.event.pull_request.title}}](https://github.com/oven-sh/bun/pull/${{github.event.number}})

            @${{ github.actor }}

            Build failed on ${{ matrix.tag }}:

            **[View build output](https://github.com/oven-sh/bun/actions/runs/${{github.run_id}})**

            [Commit ${{github.sha}}](https://github.com/oven-sh/bun/commits/${{github.sha}})
  linux-test:
    name: Tests ${{matrix.tag}}
    runs-on: namespace-profile-bun-linux-x64
    needs: [linux]
    if: github.event_name == 'pull_request'
    timeout-minutes: 20
    permissions:
      pull-requests: write
    outputs:
      failing_tests: ${{ steps.test.outputs.failing_tests }}
      failing_tests_count: ${{ steps.test.outputs.failing_tests_count }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - tag: linux-x64
          - tag: linux-x64-baseline
          # - tag: linux-x64-assertions
          # - tag: linux-x64-baseline-assertions
    steps:
      - id: checkout
        name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: false
          clean: true
      - id: download
        name: Download
        uses: actions/download-artifact@v4
        with:
          name: bun-${{matrix.tag}}
          path: ${{runner.temp}}/release
      - id: install-bun
        name: Install Bun
        run: |
          cd ${{runner.temp}}/release
          unzip bun-${{matrix.tag}}.zip
          cd bun-${{matrix.tag}}
          chmod +x bun
          pwd >> $GITHUB_PATH
      - id: bun-version-check
        name: Bun version check
        run: |
          # If this hangs, it means something is seriously wrong with the build
          bun --version
      - id: install-dependnecies
        name: Install dependencies
        run: |
          sudo apt-get update && sudo apt-get install -y openssl
          bun install --verbose
          bun install --cwd=test --verbose
          bun install --cwd=packages/bun-internal-test --verbose

          bun install --cwd=test/js/third_party/prisma --verbose

      # This is disabled because the cores are ~5.5gb each
      # so it is easy to hit 50gb coredump downloads. Only enable if you need to retrive one

      # - name: Set core dumps to get stored in /cores
      #   run: |
      #     sudo mkdir /cores
      #     sudo chmod 777 /cores
      #     # Core filenames will be of the form executable.pid.timestamp:
      #     sudo bash -c 'echo "/cores/%e.%p.%t" > /proc/sys/kernel/core_pattern'

      - id: test
        name: Test (node runner)
        env:
          SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
          TMPDIR: ${{runner.temp}}
          TLS_MONGODB_DATABASE_URL: ${{ secrets.TLS_MONGODB_DATABASE_URL }}
          TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
        # if: ${{github.event.inputs.use_bun == 'false'}}
        run: |
          ulimit -c unlimited
          ulimit -c

          node packages/bun-internal-test/src/runner.node.mjs || true
      - uses: actions/upload-artifact@v4
        if: steps.test.outputs.failing_tests != ''
        with:
          name: cores
          path: /cores
      - uses: sarisia/actions-status-discord@v1
        if: always() && steps.test.outputs.failing_tests != '' && github.event_name == 'pull_request'
        with:
          title: ""
          webhook: ${{ secrets.DISCORD_WEBHOOK }}
          status: "failure"
          noprefix: true
          nocontext: true
          description: |
            Pull Request
            ### ❌ [${{github.event.pull_request.title}}](https://github.com/oven-sh/bun/pull/${{github.event.number}})

            @${{ github.actor }}, there are ${{ steps.test.outputs.failing_tests_count }} files with test failures on ${{ matrix.tag }}:

            ${{ steps.test.outputs.failing_tests }}

            **[View test output](https://github.com/oven-sh/bun/actions/runs/${{github.run_id}})**
      - name: Comment on PR
        if: steps.test.outputs.failing_tests != '' && github.event_name == 'pull_request'
        uses: thollander/actions-comment-pull-request@v2
        with:
          comment_tag: test-failures-${{matrix.tag}}
          message: |
            ❌ @${{ github.actor }} ${{ steps.test.outputs.failing_tests_count }} files with test failures on ${{ matrix.tag }}:

            ${{ steps.test.outputs.failing_tests }}

            **[View test output](https://github.com/oven-sh/bun/actions/runs/${{github.run_id}})**

            <sup>[#${{github.sha}}](https://github.com/oven-sh/bun/commits/${{github.sha}})</sup>
      - name: Uncomment on PR
        if: steps.test.outputs.failing_tests == '' && github.event_name == 'pull_request'
        uses: thollander/actions-comment-pull-request@v2
        with:
          comment_tag: test-failures-${{matrix.tag}}
          mode: upsert
          create_if_not_exists: false
          message: |
            ✅ test failures on ${{ matrix.tag }} have been resolved.

            <sup>[#${{github.sha}}](https://github.com/oven-sh/bun/commits/${{github.sha}})</sup>
      - id: fail
        name: Fail the build
        if: steps.test.outputs.failing_tests != ''
        run: exit 1
